package cn.okcode.slowjson;

import cn.okcode.slowjson.ast.AbstractNode;
import cn.okcode.slowjson.internal.JsonException;
import cn.okcode.slowjson.internal.TypeReference;
import cn.okcode.slowjson.parser.*;

import java.util.List;

/**
 * JSON处理静态工具类
 *
 * @author pyk13
 */
public class JSON {

    private static JsonParser getParser(String jsonString) {
        return new RecursiveDescentParserImpl(jsonString, new Config());
        //return new LL1JsonParserImpl(jsonString, new Config());
        //return new NodeListenParserImpl(jsonString, new Config());
        //return new StateMachineJsonParserImpl(jsonString, new Config());
    }

    /**
     * 对象转换成json字符串
     *
     * @param object 对象
     * @return json字符串
     */
    public static String toJsonString(Object object) {
        Serializer serializer = new Serializer();
        return serializer.serialize(object);
    }

    /**
     * 转换为格式化的json字符串
     *
     * @param object 对象
     * @return 格式化的json字符串
     */
    public static String toPrettyJsonString(Object object) {
        JsonNodeWriter writer = new JsonNodeWriter();
        AbstractNode<?> node = writer.write(object);
        FormatVisitorImpl visitor = new FormatVisitorImpl(true);
        node.accept(visitor);
        return visitor.print();
    }

    /**
     * json字符串转换为对象
     *
     * @param jsonString json字符串
     * @param clazz      对象的 类型对象
     * @param <T>        类型
     * @return T指定类型的对象
     */
    public static <T> T toObject(String jsonString, Class<T> clazz) {
        JsonParser parser = getParser(jsonString);
        ObjectDeSerializeVisitorImpl<T> deSerializer = new ObjectDeSerializeVisitorImpl<>(clazz);
        parser.addVisitor(deSerializer);
        parser.parse();
        return deSerializer.getBean();
    }

    /**
     * json字符串到对象
     * <p>
     * 用法示例：{@code  List<Person> list = JSON.toObject(string, new TypeReference<List<Person>>() {}) }
     *
     * @param jsonString    json字符串
     * @param typeReference 对象的类型定义，抽象类
     * @param <T>           对象的类型
     * @return T类型的对象
     */
    public static <T> T toObject(String jsonString, TypeReference<T> typeReference) {
        JsonParser parser = getParser(jsonString);
        ObjectDeSerializeVisitorImpl<T> deSerializer = new ObjectDeSerializeVisitorImpl<>(typeReference);
        parser.addVisitor(deSerializer);
        parser.parse();
        return deSerializer.getBean();
    }

    /**
     * json字符串转换为对象数组
     *
     * @param jsonString json字符串
     * @return 对象数组，JsonArray类型，JsonArray是个List
     */
    public static JsonArray toJsonArray(String jsonString) {
        JsonParser parser = getParser(jsonString);
        if (!parser.isArray()) {
            throw new JsonException("该字符串无法转换成数组");
        }
        DefaultDeSerializeVisitorImpl deSerializer = new DefaultDeSerializeVisitorImpl();
        parser.addVisitor(deSerializer);
        parser.parse();
        return deSerializer.getJsonArray();
    }

    /**
     * 反序列化json字符串为T类型的对象数组
     *
     * @param jsonString json字符串
     * @param type       指定数组的元素类型class
     * @param <T>        指定数组的元素类型
     * @return T类型的数组
     */
    public static <T> List<T> toArray(String jsonString, Class<T> type) {
        JsonParser parser = getParser(jsonString);
        if (!parser.isArray()) {
            throw new JsonException("该字符串无法转换成数组");
        }
        ObjectDeSerializeVisitorImpl<T> deSerializer = new ObjectDeSerializeVisitorImpl<>(List.class, type);
        parser.addVisitor(deSerializer);
        parser.parse();
        return deSerializer.getBeanList();
    }

    /**
     * 反序列化json字符串为JsonObject对象
     *
     * @param jsonString json字符串
     * @return JsonObject对象
     */
    public static JsonObject toJsonObject(String jsonString) {
        JsonParser parser = getParser(jsonString);
        if (!parser.isObject()) {
            throw new JsonException("该字符串无法转换成对象");
        }
        DefaultDeSerializeVisitorImpl deSerializer = new DefaultDeSerializeVisitorImpl();
        parser.addVisitor(deSerializer);
        parser.parse();
        return deSerializer.getJsonObject();
    }

    /**
     * 反序列化为任意对象，如果是数组，则转换为JsonArray，如果是对象则转换为JsonObject，其它的转换为字符串
     *
     * @param jsonString json字符串
     * @return JsonArray、JsonObject或者String
     */
    public static Object toObject(String jsonString) {
        JsonParser parser = getParser(jsonString);
        if (parser.isArray()) {
            return toJsonArray(jsonString);
        } else if (parser.isObject()) {
            return toJsonObject(jsonString);
        } else {
            return toObject(jsonString, String.class);
        }
    }


    /**
     * 格式化JSON字符串
     *
     * @param jsonString JSON字符串
     * @return 格式化的JSON字符串
     */
    public static String prettyPrint(String jsonString) {
        JsonParser parser = getParser(jsonString);
        FormatVisitorImpl formatVisitor = new FormatVisitorImpl(true);
        parser.addVisitor(formatVisitor);
        parser.parse();
        return formatVisitor.print();
    }

    /**
     * 压缩JSON字符串
     *
     * @param jsonString JSON字符串
     * @return 压缩的JSON字符串
     */
    public static String compressPrint(String jsonString) {
        JsonParser parser = getParser(jsonString);
        FormatVisitorImpl formatVisitor = new FormatVisitorImpl(false);
        parser.addVisitor(formatVisitor);
        parser.parse();
        return formatVisitor.print();
    }
}
